//本节主要介绍this指向，如何修改this的指向，apply函数和call函数，装饰器

//方法是指对象中绑定的函数
var y=new Date().getFullYear();
console.log(y);

var xiaoming={
    name: '小明',
    birth: 1900,
    age:function(){
        var y=new Date().getFullYear();
        return y-this.birth;
    }
}
xiaoming.age; //是一个function
debugger;
var xiaoming_age=xiaoming.age();
console.log(xiaoming_age);

//javascript中的this变量设置是有缺陷的，只有在方法函数内才能指向对象
function getAge() {
    var y = new Date().getFullYear();
    return y - this.birth;
}

var xiaoming = {
    name: '小明',
    birth: 1990,
    age: getAge
};
xiaoming.age();//这个能输出正常结果
getAge();//这个输出不正常
//this指向谁 视情况而定 如果以对象的方法形式调用，比如xiaoming.age() 该函数的this指向被调用的对象
//如果单独调用函数 getAge()函数指向的是window
var fn=xiaoming.age;
fn();//先拿到xiaoming的age函数然后再调用也是不行的


'use strict' //use strict模式下this指向undefined
var xiaoming = {
    name: '小明',
    birth: 1990,
    age: function () {
        function getAgeFromBirth() {
            var y = new Date().getFullYear();
            return y - this.birth;
        }
        return getAgeFromBirth();
    }
};
xiaoming.age();//函数内部的函数调用this指针也会指向到window



//可以在方法内部使用that捕获this指针，然后到内部函数调用可以成功
var xiaoming = {
    name: '小明',
    birth: 1990,
    age: function () {
        var that = this; // 在方法内部一开始就捕获this
        function getAgeFromBirth() {
            var y = new Date().getFullYear();
            return y - that.birth; // 用that而不是this
        }
        return getAgeFromBirth();
    }
};

xiaoming.age();

//apply和call原理 apply第一个参数是要绑定的对象，第二个参数是函数的实参值 以列表的形式传递
//call和apply唯一的差别就是传递实参的时候 打散传递
//这样调用的时候this就会指向对象
function getAge() {
    var y = new Date().getFullYear();
    return y - this.birth;
}

var xiaoming = {
    name: '小明',
    birth: 1990,
    age: getAge
};

xiaoming.age(); // 25
getAge.apply(xiaoming, []);


//装饰器 实际上就是装饰函数的函数，在不修改函数的情况下，给函数增添功能
//原理是使旧函数指向新函数，apply能够改变函数的行为，因此能当作装饰器用
